// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------
// Modification history:
// feature: support multiple sending based on topic
// feature: Add topic qos feature, and add test cases
// feature: compatible with DSF
// ------------------------------------------------------------------

#ifndef XMLPARSER_TOPICQOS_HPP_
#define XMLPARSER_TOPICQOS_HPP_

#include <xmlparser/qos/XMLQosPolicies.hpp>
#include <elog/Log.hpp>

namespace vbsutil {
namespace xmlparser {

/**
 * Class TopicQos, containing all the possible Qos that can be set for a determined Topic.
 * Although these values can be set and are transmitted
 * during the Endpoint Discovery Protocol, not all of the behaviour associated with them has been
 * implemented in the library. Please consult each of them to check for implementation details and
 * default values.
 *
 * @ingroup EDDS_QOS_MODULE
 */
class TopicQos {
 public:
    /**
     * @brief Constructor
     */
    RTPS_DllAPI TopicQos();

    bool operator==(const TopicQos& b) const {
        return (this->durability_ == b.durability()) && (this->deadline_ == b.deadline()) &&
               (this->liveliness_ == b.liveliness()) && (this->reliability_ == b.reliability()) &&
               (this->history_ == b.history()) && (this->resource_limits_ == b.resource_limits()) &&
               (this->lifespan_ == b.lifespan()) && (this->ownership_ == b.ownership());
    }

    /**
     * Getter for DurabilityQosPolicy
     *
     * @return DurabilityQos reference
     */
    const DurabilityQosPolicy& durability() const { return durability_; }

    /**
     * Getter for DurabilityQosPolicy
     *
     * @return DurabilityQos reference
     */
    DurabilityQosPolicy& durability() { return durability_; }

    /**
     * Setter for DurabilityQosPolicy
     *
     * @param durability new value for the DurabilityQosPolicy
     */
    void durability(const DurabilityQosPolicy& durability) { durability_ = durability; }

    void durability_from_xml(bool from) { is_durability_from_xml_ = from; }

    const bool& durability_from_xml() const { return is_durability_from_xml_; }

    /**
     * Getter for DeadlineQosPolicy
     *
     * @return DeadlineQos reference
     */
    const DeadlineQosPolicy& deadline() const { return deadline_; }

    /**
     * Getter for DeadlineQosPolicy
     *
     * @return DeadlineQos reference
     */
    DeadlineQosPolicy& deadline() { return deadline_; }

    /**
     * Setter for DeadlineQosPolicy
     *
     * @param deadline new value for the DeadlineQosPolicy
     */
    void deadline(const DeadlineQosPolicy& deadline) { deadline_ = deadline; }

    void deadline_from_xml(bool from) { is_deadline_from_xml_ = from; }

    const bool& deadline_from_xml() const { return is_deadline_from_xml_; }

    /**
     * Getter for LivelinessQosPolicy
     *
     * @return LivelinessQos reference
     */
    const LivelinessQosPolicy& liveliness() const { return liveliness_; }

    /**
     * Getter for LivelinessQosPolicy
     *
     * @return LivelinessQos reference
     */
    LivelinessQosPolicy& liveliness() { return liveliness_; }

    /**
     * Setter for LivelinessQosPolicy
     *
     * @param liveliness new value for the LivelinessQosPolicy
     */
    void liveliness(const LivelinessQosPolicy& liveliness) { liveliness_ = liveliness; }

    /**
     * Getter for ReliabilityQosPolicy
     *
     * @return ReliabilityQos reference
     */
    const ReliabilityQosPolicy& reliability() const { return reliability_; }

    /**
     * Getter for ReliabilityQosPolicy
     *
     * @return ReliabilityQos reference
     */
    ReliabilityQosPolicy& reliability() { return reliability_; }

    /**
     * Setter for ReliabilityQosPolicy
     *
     * @param reliability new value for the ReliabilityQosPolicy
     */
    void reliability(const ReliabilityQosPolicy& reliability) { reliability_ = reliability; }

    void reliability_from_xml(bool from) { is_reliability_from_xml_ = from; }

    const bool& reliability_from_xml() const { return is_reliability_from_xml_; }

    /**
     * Getter for HistoryQosPolicy
     *
     * @return HistoryQos reference
     */
    const HistoryQosPolicy& history() const { return history_; }

    /**
     * Getter for HistoryQosPolicy
     *
     * @return HistoryQos reference
     */
    HistoryQosPolicy& history() { return history_; }

    /**
     * Setter for HistoryQosPolicy
     *
     * @param history new value for the HistoryQosPolicy
     */
    void history(const HistoryQosPolicy& history) { history_ = history; }

    void history_from_xml(bool from) { is_history_from_xml_ = from; }

    const bool& history_from_xml() const { return is_history_from_xml_; }

    /**
     * Getter for ResourceLimitsQosPolicy
     *
     * @return ResourceLimitsQos reference
     */
    const ResourceLimitsQosPolicy& resource_limits() const { return resource_limits_; }

    /**
     * Getter for ResourceLimitsQosPolicy
     *
     * @return ResourceLimitsQos reference
     */
    ResourceLimitsQosPolicy& resource_limits() { return resource_limits_; }

    /**
     * Setter for ResourceLimitsQosPolicy
     *
     * @param resource_limits new value for the ResourceLimitsQosPolicy
     */
    void resource_limits(const ResourceLimitsQosPolicy& resource_limits) { resource_limits_ = resource_limits; }

    void resource_from_xml(bool from) { is_resource_from_xml_ = from; }

    const bool& resource_from_xml() const { return is_resource_from_xml_; }

    /**
     * Getter for LifespanQosPolicy
     *
     * @return LifespanQos reference
     */
    const LifespanQosPolicy& lifespan() const { return lifespan_; }

    /**
     * Getter for LifespanQosPolicy
     *
     * @return LifespanQos reference
     */
    LifespanQosPolicy& lifespan() { return lifespan_; }

    /**
     * Setter for LifespanQosPolicy
     *
     * @param lifespan new value for the LifespanQosPolicy
     */
    void lifespan(const LifespanQosPolicy& lifespan) { lifespan_ = lifespan; }

    void lifespan_from_xml(bool from) { is_lifespan_from_xml_ = from; }

    const bool& lifespan_from_xml() const { return is_lifespan_from_xml_; }

    /**
     * Getter for OwnershipQosPolicy
     *
     * @return OwnershipQos reference
     */
    const OwnershipQosPolicy& ownership() const { return ownership_; }

    /**
     * Getter for OwnershipQosPolicy
     *
     * @return OwnershipQos reference
     */
    OwnershipQosPolicy& ownership() { return ownership_; }

    /**
     * Setter for OwnershipQosPolicy
     *
     * @param ownership new value for the OwnershipQosPolicy
     */
    void ownership(const OwnershipQosPolicy& ownership) { ownership_ = ownership; }

    void ownership_from_xml(bool from) { is_ownership_from_xml_ = from; }

    const bool& ownership_from_xml() const { return is_ownership_from_xml_; }

    /**
     * Getter for sendMulti
     *
     * @return sendMulti reference
     */
    const bool& send_multi() const { return is_send_multi_; }

    /**
     * Setter for sendMulti
     *
     * @param send_multi new value for the sendMulti
     */
    void send_multi(const bool& send_multi) { is_send_multi_ = send_multi; }

    void send_multi_from_xml(bool from) { is_send_multi_from_xml_ = from; }

    const bool& send_multi_from_xml() const { return is_send_multi_from_xml_; }

 private:
    //! Durability Qos, implemented in the library.
    DurabilityQosPolicy durability_;
    bool is_durability_from_xml_;

    //! Deadline Qos, implemented in the library.
    DeadlineQosPolicy deadline_;
    bool is_deadline_from_xml_;

    //! Liveliness Qos, implemented in the library.
    LivelinessQosPolicy liveliness_;

    //! Reliability Qos, implemented in the library.
    ReliabilityQosPolicy reliability_;
    bool is_reliability_from_xml_;

    //! History Qos, implemented in the library.
    HistoryQosPolicy history_;
    bool is_history_from_xml_;

    //! Resource Limits Qos, implemented in the library.
    ResourceLimitsQosPolicy resource_limits_;
    bool is_resource_from_xml_;

    //! Lifespan Qos, implemented in the library.
    LifespanQosPolicy lifespan_;
    bool is_lifespan_from_xml_;

    //! Ownership Qos, NOT implemented in the library.
    OwnershipQosPolicy ownership_;
    bool is_ownership_from_xml_;
    bool is_send_multi_ = false;
    bool is_send_multi_from_xml_;
};

// RTPS_DllAPI extern const TopicQos TOPIC_QOS_DEFAULT;
const TopicQos& getDefaultTopicQos();

}  // namespace xmlparser
}  // namespace vbsutil

#endif  // INCLUDE_EDDS_DDS_TOPIC_QOS_TOPICQOS_HPP_
